package ipcards.rulesets;
import ipcards.net.*;
import ipcards.*;
import ipcards.events.PlayerAction;

import java.util.Vector;
import java.lang.Integer;
import javax.swing.JOptionPane;


public class ChaseTheAceRuleSet extends Ruleset {
	
	private String deckused = "NoJokers.deck";
	private final int DECKSIZE = 52;
	private final int NUMDEALTCARDS = 1;
	private final int NUMLIVES = 5;
	private int dealerID = -1;
	
	private ChaseTheAceGame game;
	private CardsServer thisserver;
	public boolean canShuffle = false;
	public boolean canNewGame = false;
	
	public ChaseTheAceRuleSet(CardsServer s, ChaseTheAceGame g) {
		thisserver = s;
		game = g;
	}
	
	public String getDeckName() {
		return deckused;
	}
	
	public int getDeckSize() {
		return DECKSIZE;
	}
	
	public int getDealerID(){
		return dealerID;
	}
	
	public void setDealerID(int ID){
		dealerID = ID;
	}
	
	public void deal(int players, CardSet thisdeck) {
		/*dealerID++;
		if(dealerID >= players){
			dealerID = 0;
		}*/
		//Ensure there are enough cards
		/*int tempnumplayers = players.size();
		while((tempnumplayers * NUMDEALTCARDS) >= DECKSIZE)
		{
			Deck d = new Deck(deckused);
			getRoom().getTable().addDeck(d);					///ADD APPROPRIATE DECK -> done in game class as not called every deal
			tempnumplayers -= DECKSIZE;
		}
		deck = getRoom().getTable().getcards();*/
		for(Card c : thisdeck) {
			c.setFaceDown();
			//get to server model to set locallyFlippedCards = new CardSet<Card>();
			c.setLocation(465,465);
		}
				
		thisdeck.shuffle();						///SHUFFLE DECK
		
		for(int i=0; i < players; i++) {
			if(thisserver.clients.get(i) != null) {
				for(int j = 0; j < NUMDEALTCARDS; j++) {
				 	Card c = thisdeck.getCardFromZ(i * NUMDEALTCARDS + j);
				 		///ASSIGN CARDS j TO PLAYER i
				 		System.out.println(i +":" + j);
				 		
				 	c.addPermission((thisserver.clients.get(i)).thisplayer,thisserver.CONTROL, game.getRoom().getTable().getPlayer());
				 	c.addPermission((thisserver.clients.get(i)).thisplayer,thisserver.SEE, game.getRoom().getTable().getPlayer());
				 	//c.setLocation(game.getPlayerLocation(i));
				 	c.setLocation(game.getPlayerLocationCircle(i));
				 	if(c.getAttribute("rank").equalsIgnoreCase("13")) {
					 	c.setFaceUp();
					 	/*switch(Integer.parseInt(c.getAttribute("suit"))) {
						 	case 0: {
						 		game.isKing("clubs");
						 		break;
					 		}
						 	case 1: {
						 		game.isKing("spades");
						 		break;
					 		}
						 	case 2: {
						 		game.isKing("hearts");
						 		break;
					 		}
						 	case 3: {
						 		game.isKing("diamonds");
						 		break;
					 		}
				 		}*/
					 	//System.out.println("kingFlip");
				 	}
				}
				
			}
		}
	}
	
	public void deal(int players, CardSet thisdeck, boolean[] playersOut) {
		for(Card c : thisdeck) {
			c.setFaceDown();
			c.setLocation(465,465);
			
			for(Client client: thisserver.clients) {
				if(c.permissionQuery(client.thisplayer, thisserver.CONTROL)) {
					c.removePermission(client.thisplayer, thisserver.CONTROL, game.getRoom().getTable().getPlayer());
					c.removePermission(client.thisplayer, thisserver.SEE, game.getRoom().getTable().getPlayer());
				}
			}
		}
		game.getRoom().table.sModel.performPlayerAction(new PlayerAction(game.getRoom().table.sModel, PlayerAction.SET_FACE_DOWN, thisdeck.toString()));		
		game.resetLocalFlipComplete();
		thisdeck.shuffle();						///SHUFFLE DECK
		
		for(int i=0; i < players; i++) {
			if(thisserver.clients.get(i) != null && !playersOut[i]) {
				for(int j = 0; j < NUMDEALTCARDS; j++) {
				 	Card c = thisdeck.getCardFromZ(i * NUMDEALTCARDS + j);
				 		///ASSIGN CARDS j TO PLAYER i
				 		System.out.println(i +":" + j);
				 		
				 	c.addPermission((thisserver.clients.get(i)).thisplayer,thisserver.CONTROL, game.getRoom().getTable().getPlayer());
				 	c.addPermission((thisserver.clients.get(i)).thisplayer,thisserver.SEE, game.getRoom().getTable().getPlayer());
				 	//c.setLocation(game.getPlayerLocation(i));
				 	c.setLocation(game.getPlayerLocationCircle(i));
				 	if(c.getAttribute("rank").equalsIgnoreCase("13")) {
					 	c.setFaceUp();
				 	}
				}
				
			}
		}
	}
	
	public int initialLives() {
		return NUMLIVES;
	}
	
	public void sit(Client current){
		current.endTurn();
		System.out.println("Client is sitting");
	}
	
	public void cutDeck(Client current, CardSet deck, int position) {
	
		Card newCard = deck.getCardFromZ((position - 1) + (game.getRoom().players.size() - 1));
System.out.println("position cut in deck is "+position);		
		CardsServer cs = game.getRoom().controller.getServer();				//currID needed to put the new (cut) card in the correct location
		int currID = -1;
		int cID = -1;
		for(Client c: cs.clients){
			cID++;
			if(c == current){
				currID = cID;
			}
		}
System.out.println("new card for player "+currID+" is card number "+newCard.getImmutableID());		
		Card currentsCard = null;
		Card nextsCard = null;
		for(Card c : deck) {
			if(c.permissionQuery(current.thisplayer, thisserver.CONTROL)) {
				currentsCard = c;
			}
		}
System.out.println("old card for player "+currID+" is card number "+currentsCard.getImmutableID());		
		//card not being updated immediately-repaint issue
		//all cards on table swapping randomly? see email from will
		//reset local flip for the player in question		
		
//THIS CODE IS NOT WORKING IF THE CANCEL BUTTON IS PRESSED THEN THE MAXIMUM NUMBER IS USED IN THE CUT!!!!!		
				
		newCard.setLocation(game.getPlayerLocationCircle(currID));
		newCard.addPermission(current.thisplayer,thisserver.CONTROL, game.getRoom().getTable().getPlayer());
		newCard.addPermission(current.thisplayer,thisserver.SEE, game.getRoom().getTable().getPlayer());
		currentsCard.setLocation(465,465);
		currentsCard.removePermission(current.thisplayer,thisserver.CONTROL, game.getRoom().getTable().getPlayer());
		currentsCard.removePermission(current.thisplayer,thisserver.SEE, game.getRoom().getTable().getPlayer());
		game.resetLocalFlip(currentsCard);

//END OF CODE NOT WORKING......THROWS EXCEPTION ON PRINT STATEMENT 	11 LINES DOWN FROM HERE	
		
		current.endTurn();
		
Card currentsCard2 = null;
Card nextsCard2 = null;
for(Card c2 : deck) {
	if(c2.permissionQuery(current.thisplayer, thisserver.CONTROL)) {
		currentsCard2 = c2;
	}
}
System.out.println("Cards have been exchanged. new card for player "+currID+" is card number "+currentsCard2.getImmutableID());		
		
	}
	
	public void swapCards(Client current, Client next, Client dealer, CardSet deck) {
		Card currentsCard = null;
		Card nextsCard = null;
		for(Card c : deck) {
			if(c.permissionQuery(current.thisplayer, thisserver.CONTROL)) {
				currentsCard = c;
			}
			if(c.permissionQuery(next.thisplayer, thisserver.CONTROL)) {
				nextsCard = c;
			}
		}
		
		if((nextsCard.getAttribute("rank").equals("13")  && current != dealer )|| currentsCard.getAttribute("rank").equals("13"))
		{
			
			//print cannot swap with a king
			System.out.println("Cannot swap with a king. You are sitting.");
			
			current.endTurn();
			if(current == dealer){
				System.out.println("Hand is over. Determine losers.");
				game.determineLosers(game.getRoom().controller.getCardServer().clients, dealer, current);
			}
		//cut deck if dealer	
		} else if(current == dealer) { 
			
			current.getServerModel().performPlayerAction(PlayerAction.newCustomPlayerAction(this, ChaseTheAceGame.CUT, null));
			
			/*System.out.println("You are the dealer. Please cut the deck");
			boolean cutsuccess = false;
			while(!cutsuccess){
				int i = -1;
				try{
						//+1 to card numbers to make it more human-friendly
					i = Integer.parseInt((String)JOptionPane.showInputDialog(
            	        game.buttonPanel,
            	        "You are the dealer. You must cut the deck. \n Please choose the point at which to cut the deck [1-"+(52-(game.getRoom().players.size())+1)+"]",
            	        "Choose a number corresponding to the point in the deck"));
				}
				catch(NumberFormatException e){
					
				}	
				if(i > 0 && i <= (52-(game.getRoom().players.size())+1)){
					System.out.println("success");
					cutsuccess = true;
						
					//prompt user for point to cut deck....returned as int "cardID"
					Card newCard = deck.getCardFromZ((i-1)+(game.getRoom().players.size()-1));
				
					CardsServer cs = game.getRoom().controller.getServer();
					int currID = -1;
					int cID = -1;
					for(Client c: cs.clients){
						cID++;
						if(c == current){
							currID = cID;
						}
					}
//card not being updated immediately-repaint issue
//all cards on table swapping randomly? see email from will
//reset local flip for the player in question				
					newCard.setLocation(game.getPlayerLocationCircle(currID));
					newCard.addPermission(current.thisplayer,thisserver.CONTROL, game.getRoom().getTable().getTable());
					newCard.addPermission(current.thisplayer,thisserver.SEE, game.getRoom().getTable().getTable());
					currentsCard.setLocation(465,465);
					currentsCard.removePermission(current.thisplayer,thisserver.CONTROL, game.getRoom().getTable().getTable());
					currentsCard.removePermission(current.thisplayer,thisserver.SEE, game.getRoom().getTable().getTable());
				}
			}*/
			
		} else {
			
			CardsServer cs = game.getRoom().controller.getServer();
			int currID = -1;
			int nextID = -1;
			int cID = -1;
			
			for(Client c: cs.clients) {
				cID++;
				if(c == current) {
					currID = cID;
				}
				if(c == next) {
					nextID = cID;
				}
			}
//reset local flip for the two players in question
			game.resetLocalFlip(currentsCard);
			game.resetLocalFlip(nextsCard);	
			currentsCard.setLocation(game.getPlayerLocationCircle(nextID));
			nextsCard.setLocation(game.getPlayerLocationCircle(currID));
			
			//temp var to reduce # calls
			Player tmpPlayer = game.getRoom().getTable().getPlayer();
			
			nextsCard.addPermission(current.thisplayer,thisserver.CONTROL, tmpPlayer);
			nextsCard.addPermission(current.thisplayer,thisserver.SEE, tmpPlayer);
			currentsCard.removePermission(current.thisplayer,thisserver.CONTROL, tmpPlayer);
			currentsCard.removePermission(current.thisplayer,thisserver.SEE, tmpPlayer);
			currentsCard.addPermission(next.thisplayer,thisserver.CONTROL, tmpPlayer);
			currentsCard.addPermission(next.thisplayer,thisserver.SEE, tmpPlayer);
			nextsCard.removePermission(next.thisplayer,thisserver.CONTROL, tmpPlayer);
			nextsCard.removePermission(next.thisplayer,thisserver.SEE, tmpPlayer);
			
			
			/*nextsCard.addPermission(current.thisplayer,thisserver.CONTROL, game.getRoom().getTable().getPlayer());
			nextsCard.addPermission(current.thisplayer,thisserver.SEE, game.getRoom().getTable().getPlayer());
			currentsCard.removePermission(current.thisplayer,thisserver.CONTROL, game.getRoom().getTable().getPlayer());
			currentsCard.removePermission(current.thisplayer,thisserver.SEE, game.getRoom().getTable().getPlayer());
			currentsCard.addPermission(next.thisplayer,thisserver.CONTROL, game.getRoom().getTable().getPlayer());
			currentsCard.addPermission(next.thisplayer,thisserver.SEE, game.getRoom().getTable().getPlayer());
			nextsCard.removePermission(next.thisplayer,thisserver.CONTROL, game.getRoom().getTable().getPlayer());
			nextsCard.removePermission(next.thisplayer,thisserver.SEE, game.getRoom().getTable().getPlayer());*/
			
			current.getServerModel().sync();
			
			System.out.println("Cards Swapped");
			
			current.endTurn();
		}
		
	}
	
	public Vector<Client> determineLosers(Vector<Client> players, boolean[] out) {
		int initialLowestCard = 14;
		int cardvalue = 14;
		CardSet toflip = new CardSet();
		Vector<Client> losers = new Vector<Client>();
		int playernum = 0;
		for(Client player : players) {
			Card currentsCard = null;
System.out.println("looping thru players");	
			if(!out[playernum]){
System.out.println("player "+playernum+" is not out yet");	
				for(Card c : game.getRoom().table.cards) {				
					if(c.permissionQuery(player.thisplayer, thisserver.CONTROL)) {			//ERROR PRINTOUT #2: THIS LOOP OR THIS IF STATEMENT IS NOT RUNNING FOR ALL PLAYERS - GENERATES NULL POINTER EXCEPTION - DEBUG HERE
						currentsCard = c;
System.out.println("found player's card");	
					}
				}
//ERROR CAUSED BY PRESSING "CANCEL" BUTTON? - CHECK THIS - MAY NEED TO WRITE/EDIT CODE TO HANDLE CANCEL CONDITION
//testing to remove error printout #2 - null pointer exception at "toflip.add(currentsCard);" currently on line 343								
if(currentsCard == null){
	System.out.println("Card is null. Failed with CONRTOL permission. Trying SEE permission");
	for(Card c : game.getRoom().table.cards) {				
		if(c.permissionQuery(player.thisplayer, thisserver.SEE)) {			
			currentsCard = c;
System.out.println("found player's card");	
		}
	}
	if(currentsCard == null){
		System.out.println("Card is null. Failed with CONRTOL and SEE permissions. WTF?");
	}
}	
//end testing segment
					
				toflip.add(currentsCard);
				//game.getRoom().table.sModel.performPlayerAction(new PlayerAction(game.getRoom().table.sModel, PlayerAction.SET_FACE_UP, currentsCard.toString()));
//SET FACE UP IS NOT WORKING IF DECK CUT ON ALL SCREENS
				String rank = currentsCard.getAttribute("rank");
				if(rank.equalsIgnoreCase("13")) {
					cardvalue = 13;			}
				else if(rank.equalsIgnoreCase("12")) {
					cardvalue = 12;
				}
				else if(rank.equalsIgnoreCase("11")) {
					cardvalue = 11;
				}
				else if(rank.equalsIgnoreCase("14")) {
					cardvalue = 1;
				}
				else {
					cardvalue = Integer.valueOf(rank);
				}
				
				if(cardvalue == initialLowestCard) {
					losers.add(player);
				}
				else if(cardvalue < initialLowestCard) {
					losers.clear();
					losers.add(player);
					initialLowestCard = cardvalue;
				}
			}
			playernum++;
		}
//set face up not working if cards not clicked	
		game.getRoom().table.sModel.performPlayerAction(new PlayerAction(game.getRoom().table.sModel, PlayerAction.SET_FACE_UP, toflip.toString()));
		
		return losers;
	}
	
}
